<?php
// +----------------------------------------------------------------------
// | HkCms
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2021 http://www.hkcms.cn, All rights reserved.
// +----------------------------------------------------------------------
// | Author: HkCms team <admin@hkcms.cn>
// +----------------------------------------------------------------------

namespace app\install\controller;

use GuzzleHttp\Client;
use think\App;
use think\facade\Config;

class Index
{
    /**
     * 应用实例
     * @var App
     */
    protected $app;

    /**
     * 构造方法
     * @access public
     * @param  App  $app  应用对象
     */
    public function __construct(App $app)
    {
        $this->app    = $app;
        $this->view   = $this->app->view;
        $this->config = $this->app->config;

        // 控制器初始化
        $this->initialize();
    }

    /**
     * 初始化
     */
    protected function initialize()
    {
        // 定位模板位置
        $this->view->config(['view_path'=>root_path().'app'.DIRECTORY_SEPARATOR.'install'.DIRECTORY_SEPARATOR.'view'.DIRECTORY_SEPARATOR]);

        header('Content-Type:text/html;charset=utf-8;');

        $this->view->assign([
            'Title'   => $this->config->get('cms.cms_app'),
            'Powered' => 'Powered by hkcms.cn',
            'version' => $this->config->get('ver.cms_version'),
        ]);

    }

    /**
     * 安装首页
     * @return \think\response\View
     */
    public function index()
    {
        return view();
    }

    /**
     * 步骤二
     * @return mixed
     */
    public function step_2()
    {
        //错误
        $err = 0;

        $tmp = function_exists('gd_info') ? gd_info() : [];

        //GD库检测
        if (!empty($tmp['GD Version'])) {
            $gd = '<span class="correct_span">&radic;</span> 已开启';
        } else {
            $gd = '<span class="correct_span error_span">&radic;</span> 未开启';
            $err++;
        }
        //mysqli检测
        if (function_exists('mysqli_connect')) {
            $mysqli = '<span class="correct_span">&radic;</span> 已开启';
        } else {
            $mysqli = '<span class="correct_span error_span">&radic;</span> 未开启';
            $err++;
        }
        //pdo检测
        if (class_exists('pdo')) {
            $pdo = '<span class="correct_span">&radic;</span> 已开启';
        } else {
            $pdo = '<span class="correct_span error_span">&radic;</span> 未开启';
            $err++;
        }
        //pdo_mysql检测
        if (extension_loaded('pdo_mysql')) {
            $pdo_mysql = '<span class="correct_span">&radic;</span> 已开启';
        } else {
            $pdo_mysql = '<span class="correct_span error_span">&radic;</span> 未开启';
            $err++;
        }
        //上传检测
        if (ini_get('file_uploads')) {
            $uploadSize = '<span class="correct_span">&radic;</span> ' . ini_get('upload_max_filesize');
        } else {
            $uploadSize = '<span class="correct_span error_span">&radic;</span>禁止上传';
            $err++;
        }
        //session检测
        if (function_exists('session_start')) {
            $session = '<span class="correct_span">&radic;</span> 已开启';
        } else {
            $session = '<span class="correct_span error_span">&radic;</span> 未开启';
            $err++;
        }

        //目录权限检测
        $folder = array(
            '.env',
            'template'.DIRECTORY_SEPARATOR,
            'addons'.DIRECTORY_SEPARATOR,
            //'runtime'.DIRECTORY_SEPARATOR,
            'public'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR,
            'public'.DIRECTORY_SEPARATOR.'static'.DIRECTORY_SEPARATOR.'module',
            'public'.DIRECTORY_SEPARATOR.'static'.DIRECTORY_SEPARATOR.'addons'
        );
        $folderInfo = array();
        foreach ($folder as $dir) {
            $result = array(
                'dir' => $dir,
            );
            $path = root_path() . $dir;
            if (is_readable($path)) {
                $result['is_readable'] = '<span class="correct_span">&radic;</span>可读';
            } else {
                $result['is_readable'] = '<span class="correct_span error_span">&radic;</span>不可读';
                $err++;
            }
            //是否可写
            if (is_writable($path)) {
                $result['is_writable'] = '<span class="correct_span">&radic;</span>可写';
            } else {
                $result['is_writable'] = '<span class="correct_span error_span">&radic;</span>不可写';
                $err++;
            }
            $folderInfo[] = $result;
        }

        //PHP内置函数检测
        $function = array(
            'mb_strlen' => function_exists('mb_strlen'),
            'curl_init' => function_exists('curl_init'),
        );
        foreach ($function as $rs) {
            if ($rs == false) {
                $err++;
            }
        }
        $assign = [
            'os' => PHP_OS,
            'phpv' => @phpversion(),
            'gd' => $gd,
            'mysqli' => $mysqli,
            'pdo' => $pdo,
            'pdo_mysql' => $pdo_mysql,
            'uploadSize' => $uploadSize,
            'session' => $session,
            'folderInfo' => $folderInfo,
            'function' => $function,
            'err' => $err,
        ];
        $this->view->assign($assign);
        return $this->view->fetch();
    }

    /**
     * 第三步
     * @return mixed
     */
    public function step_3()
    {
        //地址
        $scriptName = !empty($_SERVER["REQUEST_URI"]) ? $scriptName = $_SERVER["REQUEST_URI"] : $scriptName = $_SERVER["PHP_SELF"];
        $rootpath = @preg_replace("/\/(I|i)nstall\/index\.php(.*)$/", "/", $scriptName);
        $rootpath = @preg_replace("/\/(I|i)nstall.php(.*)$/", "/", $rootpath);
        $sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
        $domain = empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
        if ((int) $_SERVER['SERVER_PORT'] != 80) {
            $domain .= ":" . $_SERVER['SERVER_PORT'];
        }
        $domain = $sys_protocal . $domain . $rootpath;
        $parse_url = parse_url($domain);
        $parse_url['path'] = str_replace('install.php', '', $parse_url['path']);
        $this->view->assign('parse_url', $parse_url);
        return $this->view->fetch();
    }

    /**
     * 数据库安装
     * @return mixed
     */
    public function step_4()
    {
        $this->view->assign('data', json_encode($_POST));
        return $this->view->fetch();
    }

    /**
     * 安装完成
     * @return mixed
     */
    public function step_5()
    {
        try {
            $client = new Client(['base_uri' => Config::get('cms.api_url')]);
            $client->request('POST', 'count/add', [
                'form_params' => [
                    'type' => 1,
                    'domain' => request()->host(),
                    'ip' => request()->ip(),
                    'version' => Config::get('ver.cms_version'),
                ]
            ]);
        } catch (\Throwable $exception) {}
        @touch(root_path() . 'runtime' . DIRECTORY_SEPARATOR . 'install.lock');
        $a = input('a');
        $this->view->assign('a',$a);
        return $this->view->fetch();
    }

    /**
     * 数据库安装
     */
    public function mysql()
    {
        $n = intval($_GET['n']);

        $arr = array();

        $dbHost = trim($_POST['dbhost']);
        $dbPort = trim($_POST['dbport']);
        $dbName = trim($_POST['dbname']);
        $dbHost = empty($dbPort) || $dbPort == 3306 ? $dbHost : $dbHost . ':' . $dbPort;
        $dbUser = trim($_POST['dbuser']);
        $dbPwd = trim($_POST['dbpw']);
        $dbPrefix = empty($_POST['dbprefix']) ? 'hkcms_' : trim($_POST['dbprefix']);

        $username = trim($_POST['manager']);
        $password = trim($_POST['manager_pwd']);
        //网站名称
        $site_name = addslashes(trim($_POST['sitename']));
        //网站域名
        //$site_url = trim($_POST['siteurl']);
        //$_site_url = parse_url($site_url);
        //网站简介
        $seo_description = trim($_POST['siteinfo']);
        //关键词
        $seo_keywords = trim($_POST['sitekeywords']);
        //邮箱地址
        $siteemail = trim($_POST['manager_email']);
        //测试数据
        $testdata = isset($_POST['testdata']) ? $_POST['testdata'] : 0;

        $conn = @mysqli_connect($dbHost, $dbUser, $dbPwd);
        if (!$conn) {
            $arr['msg'] = "连接数据库失败!";
            echo json_encode($arr);
            exit;
        }
        mysqli_query($conn,"SET NAMES 'utf8'"); //,character_set_client=binary,sql_mode='';
        $version = mysqli_get_server_info($conn);
        if ($version < 5.6) {
            $arr['msg'] = '数据库版本太低!';
            echo json_encode($arr);
            exit;
        }

        if (!mysqli_select_db($conn, $dbName)) {
            //创建数据时同时设置编码
            if (!mysqli_query($conn,"CREATE DATABASE IF NOT EXISTS `" . $dbName . "` DEFAULT CHARACTER SET utf8;")) {
                $arr['msg'] = '数据库 ' . $dbName . ' 不存在，也没权限创建新的数据库！';
                echo json_encode($arr);
                exit;
            }
            if (empty($n)) {
                $arr['n'] = 1;
                $arr['msg'] = "成功创建数据库:{$dbName}<br>";
                echo json_encode($arr);
                exit;
            }
            mysqli_select_db($conn, $dbName);
        }

        //读取数据文件
        $sqldata = file_get_contents(app_path() . 'data/hkcms.sql');
        //读取测试数据
        if ($testdata) {
            $sqldataDemo = file_get_contents(app_path() . 'data/hkcms_demo.sql');
            $sqldata = $sqldata . "\r\n" . $sqldataDemo;
        }
        $sqlFormat = sql_split($sqldata, $dbPrefix);
        /**
          执行SQL语句
         */
        $counts = count($sqlFormat);
        for ($i = $n; $i < $counts; $i++) {
            $sql = trim($sqlFormat[$i]);
            if (strstr($sql, 'CREATE TABLE')) {
                preg_match('/CREATE TABLE `([^ ]*)`/', $sql, $matches);
                mysqli_query($conn,"DROP TABLE IF EXISTS `$matches[1]`");
                $ret = mysqli_query($conn, $sql);
                if ($ret) {
                    $message = '<li><span class="correct_span">&radic;</span>创建数据表' . $matches[1] . '，完成</li> ';
                } else {
                    $message = '<li><span class="correct_span error_span">&radic;</span>创建数据表' . $matches[1] . '，失败</li>';
                }
                $i++;
                $arr = array('n' => $i, 'msg' => $message);
                echo json_encode($arr);
                exit;
            } else {
                $ret = mysqli_query($conn,$sql);
                $message = '';
                $arr = array('n' => $i, 'msg' => $message);
            }
        }

        if ($i == 999999)
            exit;
        //更新配置信息
        mysqli_query($conn,"UPDATE `{$dbPrefix}config` SET  `value` = '$site_name' WHERE name='title'");
        //mysqli_query($conn,"UPDATE `{$dbPrefix}config` SET  `value` = '$site_url' WHERE name='url' ");
        mysqli_query($conn,"UPDATE `{$dbPrefix}config` SET  `value` = '$seo_description' WHERE name='description'");
        mysqli_query($conn,"UPDATE `{$dbPrefix}config` SET  `value` = '$seo_keywords' WHERE name='keyword'");
        //mysqli_query($conn,"UPDATE `{$dbPrefix}config` SET  `value` = '$siteemail' WHERE name='email'");

        //读取配置文件，并替换真实配置数据
        $strConfig = file_get_contents( app_path() . 'data'.DIRECTORY_SEPARATOR.'example.env');
        $strConfig = str_replace('#DB_HOST#', $dbHost, $strConfig);
        $strConfig = str_replace('#DB_NAME#', $dbName, $strConfig);
        $strConfig = str_replace('#DB_USER#', $dbUser, $strConfig);
        $strConfig = str_replace('#DB_PWD#', $dbPwd, $strConfig);
        $strConfig = str_replace('#DB_PORT#', $dbPort, $strConfig);
        $strConfig = str_replace('#DB_PREFIX#', $dbPrefix, $strConfig);
        @file_put_contents(root_path() . '.env', $strConfig);

        //生成随机认证码
        $verify = get_random_str(6);
        $time = time();
        $ip = $this->app->request->ip();

        //插入管理员
        $password = md5(sha1($password) . md5($verify));
        $query = "INSERT INTO `{$dbPrefix}admin` VALUES ('1', '{$username}', '{$username}', '{$siteemail}', '{$password}', '{$verify}', '', '备注信息', '{$time}', '{$ip}', '1', '{$time}', '{$time}');";
        mysqli_query($conn,$query);
        $message = '<span class="correct_span">&radic;</span>成功添加管理员<br /><span class="correct_span">&radic;</span>成功写入配置文件<br><span class="correct_span">&radic;</span>安装完成．．．';
        $arr = array('n' => 999999, 'msg' => $message, 'a' => 'admin');
        echo json_encode($arr);
        exit;
    }

    /**
     * 测试数据库
     */
    public function testdbpwd()
    {
        $dbHost = $_POST['dbHost'] . ':' . $_POST['dbPort'];
        $conn = @mysqli_connect($dbHost, $_POST['dbUser'], $_POST['dbPwd']);
        if ($conn) {
            exit("1");
        } else {
            exit("");
        }
    }

}
